package com.config;

import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * 1.配置数据源，DataSource
 *
 * 2.配置数据连接Session工厂， SqlSessionFactoryBean
 *
 * 3.配置Mybatis Mapper， MapperScannerConfigurer
 *
 * 4.配置事务管理器， DataSourceTransactionManager
 */

@Configuration
//用于Spring扫描包
@ComponentScan("com.*")
//使用事务驱动管理器
@EnableTransactionManagement
//实现接口 TransactionManagementConfigurer， 这样可以配置注解驱动事务
public class RootConfig implements TransactionManagementConfigurer {
    private DataSource dataSource = null;

    @Override
    @Bean("annotationDrivenTransactionManager")
    public TransactionManager annotationDrivenTransactionManager() {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(initDataSource());
        return transactionManager;
    }

    /**
     * 配置数据库
     * @return
     */
    @Bean(name = "dataSource")
    public DataSource initDataSource(){
        if(dataSource != null){
            return dataSource;
        }
        Properties props = new Properties();
        props.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
        props.setProperty("url", "jdbc:mysql://localhost:3306/test_db?characterEncoding=utf8&serverTimezone=GMT-8");
        props.setProperty("username", "root");
        props.setProperty("password", "111111");
        try {
            dataSource = BasicDataSourceFactory.createDataSource(props);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataSource;
    }

    /**
     * 配置SqlSessionFactoryBean
     * @return
     */
    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactoryBean initSqlSessionFactory(){
        SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(initDataSource());
        //配置MyBatis配置文件
        Resource resource = new ClassPathResource("mybatis-config.xml");
        sqlSessionFactory.setConfigLocation(resource);
        return sqlSessionFactory;
    }

    /**
     * 通过自动扫描，发现MyBatis Mapper接口
     * @return Mapper 容器
     */
    @Bean(name = "mapperScannerConfigurer")
    public MapperScannerConfigurer initMapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        // 扫描包
        msc.setBasePackage("com.*");
        // 添加数据连接工厂
        msc.setSqlSessionFactoryBeanName("sqlSessionFactory");

        // 区分注解扫描, 只扫描带有@Repository注解的接口
        msc.setAnnotationClass(Repository.class);
        return msc;
    }


}
